package com.jvxb.demo.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jvxb.demo.entity.AccessLog;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.IdsQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@Slf4j
@RestController
@RequestMapping("/es")
@Api(tags = "es控制器")
public class EsController {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @PostMapping("/save")
    public Object save(@RequestBody AccessLog accessLog) {
        try {
            //使用uuid作为主键
            accessLog.setId(IdUtil.simpleUUID());
            Date currentDate = new Date();
            accessLog.setRequestTime(currentDate.getTime());
            accessLog.setRequestTimeStr(DateUtil.formatDateTime(currentDate));
            IndexRequest indexRequest = new IndexRequest()
                    .index("access_log")
                    .id(accessLog.getId())
                    .source(JSON.toJSONString(accessLog), XContentType.JSON);
            IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
            log.info("创建状态：{}", response.status());
            return response;
        } catch (Exception e) {
            return e.getMessage();
        }
    }

    @GetMapping("/get/{id}")
    public Object get(@PathVariable("id") String id) {
        AccessLog accessLog = null;
        try {
            GetRequest getRequest = new GetRequest("access_log", id);
            GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
            // 将 JSON 转换成对象
            if (getResponse.isExists()) {
                accessLog = JSON.parseObject(getResponse.getSourceAsBytes(), AccessLog.class);
                log.info("accessLog：{}", accessLog);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return accessLog;
    }

    @PostMapping("/get/ids")
    public Object getIds(@RequestBody Map param) {
        List<AccessLog> result = new ArrayList<>();
        try {
            IdsQueryBuilder idsQueryBuilder = new IdsQueryBuilder().addIds(((List<String>) param.get("ids")).toArray(new String[]{}));
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(idsQueryBuilder);
            SearchRequest searchRequest = new SearchRequest().source(searchSourceBuilder);
            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            //获取到结果
            SearchHits hits = response.getHits();
            Iterator<SearchHit> iterator = hits.iterator();
            while (iterator.hasNext()) {
                result.add(JSONObject.parseObject(iterator.next().getSourceAsString(), AccessLog.class));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @GetMapping("/getList")
    public Object getList(String userName) {
        List<AccessLog> result = new ArrayList<>();
        try {
            //构造查询语句
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            if (StrUtil.isNotBlank(userName)) {
                TermQueryBuilder userNameTermQueryBuilder = new TermQueryBuilder("userName", userName);
                searchSourceBuilder.query(userNameTermQueryBuilder);
            }
            log.info("dsl：{}", searchSourceBuilder.toString());
            //发起查询
            SearchRequest searchRequest = new SearchRequest().indices("access_log").source(searchSourceBuilder);
            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            //获取到结果
            SearchHits hits = response.getHits();
            Iterator<SearchHit> iterator = hits.iterator();
            while (iterator.hasNext()) {
                result.add(JSONObject.parseObject(iterator.next().getSourceAsString(), AccessLog.class));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @PostMapping("/update")
    public Object update(@RequestBody AccessLog accessLog) {
        try {
            //如果需要更新为null值则使用 JSON.toJSONString(accessLog, SerializerFeature.WriteMapNullValue)
            UpdateRequest updateRequest = new UpdateRequest().index("access_log").id(accessLog.getId())
                    .doc(JSON.toJSONString(accessLog), XContentType.JSON);
            UpdateResponse response = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
            log.info("更新状态：{}", response.status());
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }

    @PostMapping("/delete/{id}")
    public Object delete(@PathVariable String id) {
        try {
            DeleteRequest deleteRequest = new DeleteRequest().index("access_log").id(id);
            DeleteResponse response = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
            log.info("删除状态：{}", response.status());
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }
}